import requests
import time
from requests.adapters import HTTPAdapter
from requests.exceptions import RequestException, HTTPError, ConnectionError, Timeout
from urllib3.util.retry import Retry
from app.config import logger
from app.utils.proxy_pool import ProxyPool

# 使用的是星宿代理
proxyMeta = ProxyPool.proxy_xingsu


class HttpClient:
    def __init__(
        self,
        base_url,
        retries=5,
        backoff_factor=1,
        status_forcelist=None,
        allowed_methods=None,
    ):
        self.base_url = base_url
        self.session = self._create_session(
            retries, backoff_factor, status_forcelist, allowed_methods
        )

    def _create_session(
        self, retries, backoff_factor, status_forcelist, allowed_methods
    ):
        session = requests.Session()
        retries = Retry(
            total=retries,
            backoff_factor=backoff_factor,
            status_forcelist=status_forcelist or [500, 502, 503, 504],
            allowed_methods=allowed_methods or ["HEAD", "GET", "OPTIONS", "POST"],
            raise_on_status=False,
        )
        adapter = HTTPAdapter(max_retries=retries)
        session.mount("http://", adapter)
        session.mount("https://", adapter)
        return session

    def request(self, method, url, use_proxy, **kwargs):
        proxies = {"http": proxyMeta, "https": proxyMeta} if use_proxy else None
        start_time = time.time()
        try:
            response = self.session.request(method, url, proxies=proxies, **kwargs)
            response.raise_for_status()
            logger.info(
                f"请求{url}成功,请求的方法是{method}，响应状态码: {response.status_code}"
            )
        except HTTPError as http_err:
            logger.error(f"HTTP 错误: {http_err}")
        except ConnectionError as conn_err:
            logger.error(f"连接错误: {conn_err}")
        except Timeout as timeout_err:
            logger.error(f"请求超时: {timeout_err}")
        except RequestException as req_err:
            logger.error(f"请求错误: {req_err}")
        else:
            elapsed_time = time.time() - start_time
            logger.info(f"请求成功，耗时: {elapsed_time:.2f}秒")
            return response
        elapsed_time = time.time() - start_time
        logger.info(f"请求失败，耗时: {elapsed_time:.2f}秒")
        return None

    def post(self, url, use_proxy, **kwargs):
        """
        发起 POST 请求
        :param url: 请求的相对路径
        :param kwargs: 其他请求参数
        :param use_proxy: 是否使用代理
        :return: 响应对象或 None
        """
        return self.request("POST", url, use_proxy, **kwargs)

    def get(self, url, use_proxy, **kwargs):
        """
        发起 GET 请求
        :param url: 请求的相对路径
        :param kwargs: 其他请求参数
        :param use_proxy: 是否使用代理
        :return: 响应对象或 None
        """
        return self.request("GET", url, use_proxy, **kwargs)
